package com.summer.plugin.wechat;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.DigestUtils;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.lang.reflect.Field;
import java.net.ConnectException;
import java.net.URL;
import java.util.*;


/**
 * 微信通用工具类
 */
@Slf4j
public class WechatPayUtil {

	private static Logger logger = LoggerFactory.getLogger (WechatPayUtil.class);

	/**
	 * 发送https请求
	 * 
	 * @param requestUrl
	 *            请求地址
	 * @param requestMethod
	 *            请求方式（GET、POST）
	 * @param outputStr
	 *            提交的数据
	 * @return 服务器返回结果
	 */
	public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {

		String result = null;
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
			conn.setSSLSocketFactory(ssf);

			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			conn.setRequestMethod(requestMethod);

			// 当outputStr不为null时向输出流写数据
			if (null != outputStr) {
				OutputStream outputStream = conn.getOutputStream();
				// 注意编码格式
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 从输入流读取返回内容
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}

			// 释放资源
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			conn.disconnect();
			result = buffer.toString();
		} catch (ConnectException ce) {
			ce.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(result);
		return result;
	}

	/**
	 * URL编码（utf-8）
	 */
	public static String urlEncodeUTF8(String source) {
		String result = source;
		try {
			result = java.net.URLEncoder.encode(source, "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 根据内容类型判断文件扩展名
	 */
	public static String getFileExt(String contentType) {
		String fileExt = "";
		if ("image/jpeg".equals(contentType))
			fileExt = ".jpg";
		else if ("audio/mpeg".equals(contentType))
			fileExt = ".mp3";
		else if ("audio/amr".equals(contentType))
			fileExt = ".amr";
		else if ("video/mp4".equals(contentType))
			fileExt = ".mp4";
		else if ("video/mpeg4".equals(contentType))
			fileExt = ".mp4";
		return fileExt;
	}

	public static String getSign(Object bean, String wechatPayKey) {
		List<String> list = new ArrayList<String>();
		Class<? extends Object> c = bean.getClass();
		Field[] fields = c.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			Field field = fields[i];
			field.setAccessible(true); // 设置些属性是可以访问的
			Object val = null;
			try {
				val = field.get(bean);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}// 得到此属性的值
			String name = field.getName();// 得到此属性的名字
			if (val != null && "sign".equals(name) == false) {
				list.add(name + "=" + val.toString());
			}
		}
		Object[] os = list.toArray();
		Arrays.sort(os);
		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 0; i < os.length; i++) {
			if (i > 0) {
				stringBuffer.append("&");
			}
			stringBuffer.append(os[i]);
		}
		stringBuffer.append("&key=");
		stringBuffer.append(wechatPayKey);
		String content = stringBuffer.toString();
		logger.info("【微信签名字符串】" + content);

		String sign = null;
		try {
			sign = DigestUtils.md5DigestAsHex(content.getBytes("utf-8")).toString();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return sign.toUpperCase();
	}

	public static String getWXSign(HashMap<String,String> map, String appKey) {

        List<String> signList = new ArrayList<String>();
        Set<String> keys =  map.keySet();
        for (String key : keys) {
            signList.add(key);
        }

        Collections.sort(signList);
        String sign = "";
        for (int i = 0; i < signList.size(); i++) {
            String key = signList.get(i);
            String value = map.get(key);
            sign = sign + key + "=" + value + "&";
        }

        sign = sign + "key=" + appKey;
        logger.info("【微信签名字符串】" + sign);
        try {
			sign = DigestUtils.md5DigestAsHex(sign.getBytes("utf-8")).toString();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
        return sign.toUpperCase();
    }
	
	public static String getSignByMap(Map<String, String> map, String wechatPayKey) {

		List<String> list = new ArrayList<String>();
		for (String key : map.keySet()) {
			if (key == null) {
				continue;
			}
			list.add(key + "=" + map.get(key).toString());
		}
		Object[] os = list.toArray();
		Arrays.sort(os);
		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 0; i < os.length; i++) {
			if (i > 0) {
				stringBuffer.append("&");
			}
			stringBuffer.append(os[i]);
		}
		stringBuffer.append("&key=");
		stringBuffer.append(wechatPayKey);

		String content = stringBuffer.toString();
		logger.info("【微信签名字符串】" + content);

		String sign = null;
		try {
			sign = DigestUtils.md5DigestAsHex(content.getBytes("utf-8")).toString();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return sign.toUpperCase();
	}
}